package com.note.common.vo;

import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.Data;
import org.springframework.http.HttpStatus;

import java.io.Serial;
import java.io.Serializable;

/**
 * 通用响应类
 * 统一API返回格式
 */
@Data
@Tag(name = "ResponseVo", description = "统一返回处理")
public class ResponseVo<T> implements Serializable {

    @Serial
    private static final long serialVersionUID = 1L;

    /**
     * 通用状态码
     */
    public static final int CODE_SUCCESS = 200;
    public static final int CODE_FAILED = 500;
    public static final int CODE_UNAUTHORIZED = 401;
    public static final int CODE_FORBIDDEN = 403;
    public static final int CODE_NOT_FOUND = 404;
    public static final int CODE_PARAM_ERROR = 400;

    @Schema(description = "状态码 200成功 其他失败", example = "200")
    private int code;

    @Schema(description = "请求状态 true成功 false失败", example = "true")
    private Boolean status;

    @Schema(description = "状态描述信息", example = "操作成功")
    private String message;

    @Schema(description = "响应数据")
    private T data;

    /**
     * 无参构造
     */
    private ResponseVo() {
        super();
    }

    /**
     * 基础构造方法
     * 
     * @param code    状态码
     * @param status  请求状态
     * @param message 描述信息
     */
    public ResponseVo(int code, boolean status, String message) {
        this.code = code;
        this.status = status;
        this.message = message;
        this.data = null;
    }

    /**
     * 完整构造方法
     * 
     * @param code    状态码
     * @param status  请求状态
     * @param message 描述信息
     * @param data    数据
     */
    public ResponseVo(int code, boolean status, String message, T data) {
        this.code = code;
        this.status = status;
        this.message = message;
        this.data = data;
    }

    /**
     * 成功响应（无数据）
     * 
     * @return 成功响应
     */
    public static <T> ResponseVo<T> success() {
        return new ResponseVo<>(CODE_SUCCESS, true, "操作成功");
    }

    /**
     * 成功响应（带消息）
     * 
     * @param message 成功消息
     * @return 成功响应
     */
    public static <T> ResponseVo<T> success(String message) {
        return new ResponseVo<>(CODE_SUCCESS, true, message);
    }

    /**
     * 成功响应（带数据）
     * 
     * @param data 响应数据
     * @return 成功响应
     */
    public static <T> ResponseVo<T> success(T data) {
        return new ResponseVo<>(CODE_SUCCESS, true, "操作成功", data);
    }

    /**
     * 成功响应（带消息和数据）
     * 
     * @param message 成功消息
     * @param data    响应数据
     * @return 成功响应
     */
    public static <T> ResponseVo<T> success(String message, T data) {
        return new ResponseVo<>(CODE_SUCCESS, true, message, data);
    }

    /**
     * 失败响应（通用错误）
     * 
     * @return 失败响应
     */
    public static <T> ResponseVo<T> error() {
        return new ResponseVo<>(CODE_FAILED, false, "操作失败");
    }

    /**
     * 失败响应（带消息）
     * 
     * @param message 错误消息
     * @return 失败响应
     */
    public static <T> ResponseVo<T> error(String message) {
        return new ResponseVo<>(CODE_FAILED, false, message);
    }

    /**
     * 失败响应（带状态码和消息）
     * 
     * @param code    错误码
     * @param message 错误消息
     * @return 失败响应
     */
    public static <T> ResponseVo<T> error(int code, String message) {
        return new ResponseVo<>(code, false, message);
    }

    /**
     * 参数错误响应
     * 
     * @param message 错误消息
     * @return 参数错误响应
     */
    public static <T> ResponseVo<T> paramError(String message) {
        return new ResponseVo<>(CODE_PARAM_ERROR, false, message);
    }

    /**
     * 未授权响应
     * 
     * @return 未授权响应
     */
    public static <T> ResponseVo<T> unauthorized() {
        return new ResponseVo<>(CODE_UNAUTHORIZED, false, "未登录或token已过期");
    }

    /**
     * 无权限响应
     * 
     * @return 无权限响应
     */
    public static <T> ResponseVo<T> forbidden() {
        return new ResponseVo<>(CODE_FORBIDDEN, false, "没有操作权限");
    }

    /**
     * 返回资源不存在错误（404）
     */
    public static <T> ResponseVo<T> notFound() {
        return error(HttpStatus.NOT_FOUND.value(), "资源不存在");
    }
    
    /**
     * 返回资源不存在错误（404）
     * @param message 错误消息
     */
    public static <T> ResponseVo<T> notFound(String message) {
        return error(HttpStatus.NOT_FOUND.value(), message);
    }
}
